package cn.heyige.backend.service.impl;

import cn.heyige.backend.dto.DivinationResult;
import cn.heyige.backend.service.CacheService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 缓存服务实现类 - 精简版
 *
 * 专注于核心缓存管理功能，提高系统性能和可维护性
 * 增强数据验证和错误处理
 *
 * @author CodeBuddy
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class CacheServiceImpl implements CacheService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    
    private static final long DEFAULT_TIMEOUT_SECONDS = 3600; // 默认过期时间1小时
    
    @Override
    public void cacheDivinationResult(String key, DivinationResult result, long timeout) {
        // 参数校验
        if (!StringUtils.hasText(key)) {
            log.warn("缓存占卜结果失败：key为空");
            return;
        }

        if (result == null) {
            log.warn("缓存占卜结果失败：result为空");
            return;
        }

        try {
            long actualTimeout = timeout > 0 ? timeout : DEFAULT_TIMEOUT_SECONDS;
            redisTemplate.opsForValue().set(key, result, actualTimeout, TimeUnit.SECONDS);
            log.debug("缓存占卜结果成功，key: {}, timeout: {}s", key, actualTimeout);
        } catch (Exception e) {
            log.error("缓存占卜结果失败，key: {}, timeout: {}s", key, timeout, e);
            throw new RuntimeException("缓存占卜结果失败: " + e.getMessage());
        }
    }
    
    @Override
    public DivinationResult getDivinationResult(String key) {
        // 参数校验
        if (!StringUtils.hasText(key)) {
            log.warn("获取占卜结果失败：key为空");
            return null;
        }

        try {
            Object result = redisTemplate.opsForValue().get(key);
            if (result instanceof DivinationResult) {
                log.debug("从缓存获取占卜结果成功，key: {}", key);
                return (DivinationResult) result;
            }
            log.debug("缓存中未找到占卜结果，key: {}", key);
            return null;
        } catch (Exception e) {
            log.error("从缓存获取占卜结果失败，key: {}", key, e);
            return null;
        }
    }
    
    @Override
    public void evictCache(String key) {
        // 参数校验
        if (!StringUtils.hasText(key)) {
            log.warn("删除缓存失败：key为空");
            return;
        }

        try {
            redisTemplate.delete(key);
            log.debug("删除缓存成功，key: {}", key);
        } catch (Exception e) {
            log.error("删除缓存失败，key: {}", key, e);
            throw new RuntimeException("删除缓存失败: " + e.getMessage());
        }
    }
    
    @Override
    public void evictCaches(Set<String> keys) {
        // 参数校验
        if (keys == null || keys.isEmpty()) {
            log.warn("批量删除缓存失败：keys为空");
            return;
        }

        try {
            redisTemplate.delete(keys);
            log.debug("批量删除缓存成功，key数量: {}", keys.size());
        } catch (Exception e) {
            log.error("批量删除缓存失败，key数量: {}", keys.size(), e);
            throw new RuntimeException("批量删除缓存失败: " + e.getMessage());
        }
    }
    
    @Override
    public boolean hasKey(String key) {
        // 参数校验
        if (!StringUtils.hasText(key)) {
            log.warn("检查缓存存在性失败：key为空");
            return false;
        }

        try {
            return Boolean.TRUE.equals(redisTemplate.hasKey(key));
        } catch (Exception e) {
            log.error("检查缓存存在性失败，key: {}", key, e);
            return false;
        }
    }
    
    @Override
    public boolean expire(String key, long timeout) {
        // 参数校验
        if (!StringUtils.hasText(key)) {
            log.warn("设置缓存过期时间失败：key为空");
            return false;
        }

        if (timeout <= 0) {
            log.warn("设置缓存过期时间失败：timeout无效");
            return false;
        }

        try {
            return Boolean.TRUE.equals(redisTemplate.expire(key, timeout, TimeUnit.SECONDS));
        } catch (Exception e) {
            log.error("设置缓存过期时间失败，key: {}, timeout: {}s", key, timeout, e);
            return false;
        }
    }
    
    @Override
    public long getExpire(String key) {
        // 参数校验
        if (!StringUtils.hasText(key)) {
            log.warn("获取缓存过期时间失败：key为空");
            return -1;
        }

        try {
            Long expire = redisTemplate.getExpire(key, TimeUnit.SECONDS);
            return expire != null ? expire : -1;
        } catch (Exception e) {
            log.error("获取缓存过期时间失败，key: {}", key, e);
            return -1;
        }
    }
}